package top.superflow.entity.util

import javax.persistence.{Column, Index}
import org.apache.commons.lang3.StringUtils
import top.superflow.db.api.{DBField, DBIndex}
import top.superflow.exception.RequestUnsupportedException
import top.superflow.verify.Ensure

import scala.collection.mutable.ListBuffer

class JPAUtil{
  
  
  def test = {
    println()
  }
}
object JPAUtil extends Ensure {
  
  def getAllFields(entity : Any): List[DBField] = {
    
    notNull(entity)
    
    entity match {
      case target : Class[_] =>{
        createFields(target)
      }
      case _ => throw new RequestUnsupportedException(entity)
    }
  }

  private def createFields(target: Class[_]) = {
    val fields = ListBuffer[DBField]()
    for (x <- target.getDeclaredFields) {
      if (x.isAnnotationPresent(classOf[Column])) {
        val field = new DBField
        field.name = x.getName
        field.fieldType = x.getType.getName
        fillColumnFromAnnotation(field, x.getDeclaredAnnotation(classOf[Column]))
        setIndex(field, x.getDeclaredAnnotation(classOf[Index]))
        fields += field
      }
    }
    fields.toList
  }
  
  private def fillColumnFromAnnotation(field : DBField, fieldAnnotation : Column){
    if(field == null || fieldAnnotation == null) return;
    field.nullable = fieldAnnotation.nullable()
    field.length = fieldAnnotation.length()
    field.scale = fieldAnnotation.scale()
    field.precision = fieldAnnotation.precision()
  }
  
  private def setIndex(field : DBField, index : Index){
    if(field == null || index == null) return;
    
    val indexWrapper = new DBIndex
    indexWrapper.fieldList =  splitToList(index.columnList())
    indexWrapper.unique = index.unique()
    indexWrapper.name = index.name()
    
    field.indexes = List(indexWrapper)
  }
  
  
  def getIndexes(entity : Any) : List[DBIndex] = {
    
    notNull(entity)
    
    entity match {
      case target : Class[_] =>{
        val indexes = ListBuffer[DBIndex]()
        for (x <- target.getAnnotationsByType(classOf[Index])) {
            val index = new DBIndex
            index.name =  x.name()
            index.unique = x.unique()
            index.fieldList = splitToList(x.columnList())
            
            indexes += index
        }
        indexes.toList
      }
      case _ => throw new RequestUnsupportedException(entity)
    }
  }
  
  private def splitToList(originalString : String) : List[String] = {
    if(StringUtils.isEmpty(originalString)) return List()
    StringUtils.split(originalString,",").map(_.trim).toList
  }
}